package set

var _ Set[int] = NewUnsafeSet[int]()

// UnsafeSet 定义非并发安全的集合类型
type UnsafeSet[T comparable] struct {
	elems map[T]struct{}
}

// NewUnsafeSet 新建一个非并发安全的集合
func NewUnsafeSet[T comparable](elems ...T) *UnsafeSet[T] {
	set := &UnsafeSet[T]{make(map[T]struct{})}
	for _, val := range elems {
		set.elems[val] = empty
	}

	return set
}

// Add 添加元素到集合
func (own *UnsafeSet[T]) Add(elems ...T) {
	for _, elem := range elems {
		own.elems[elem] = empty
	}
}

// Delete 从集合中删除元素
func (own *UnsafeSet[T]) Delete(elems ...T) {
	for _, elem := range elems {
		delete(own.elems, elem)
	}
}

// HasAll 判断所有指定元素是否存在于集合
func (own *UnsafeSet[T]) HasAll(elems ...T) bool {
	for _, elem := range elems {
		if _, ok := own.elems[elem]; !ok {
			return false
		}
	}

	return true
}

// HasAny 判断任一指定元素是存在于集合
func (own *UnsafeSet[T]) HasAny(elems ...T) bool {
	for _, elem := range elems {
		if _, ok := own.elems[elem]; ok {
			return true
		}
	}

	return false
}

// GetLength 获取集合长度
func (own *UnsafeSet[T]) GetLength() int {
	return len(own.elems)
}

// GetElements 获取集合的所有元素
func (own *UnsafeSet[T]) GetElements() []T {
	elems := make([]T, 0, len(own.elems))
	for elem := range own.elems {
		elems = append(elems, elem)
	}

	return elems
}

// GetMap 获取集合的字典格式
func (own *UnsafeSet[T]) GetMap() map[T]struct{} {
	elems := make(map[T]struct{})
	for elem := range own.elems {
		elems[elem] = struct{}{}
	}

	return elems
}

// IsEmpty 判断集合是否为空
func (own *UnsafeSet[T]) IsEmpty() bool {
	return len(own.elems) == 0
}

// IsEqualTo 判断两集合的元素是否完全相同
func (own *UnsafeSet[T]) IsEqualTo(other Set[T]) bool {
	if len(own.elems) != other.GetLength() {
		return false
	}

	return own.IsSubsetOf(other)
}

// IsSubsetOf 判断当前集合是否是指定集合的子集
func (own *UnsafeSet[T]) IsSubsetOf(other Set[T]) bool {
	elems := other.GetMap()
	for elem := range own.elems {
		if _, ok := elems[elem]; !ok {
			return false
		}
	}

	return true
}

// IsSupersetOf 判断当前集合是否为指定集合的超集
func (own *UnsafeSet[T]) IsSupersetOf(other Set[T]) bool {
	for _, elem := range other.GetElements() {
		if _, ok := own.elems[elem]; !ok {
			return false
		}
	}

	return true
}

// Unite 求并集（不修改原集合，生成一个新的集合）
func (own *UnsafeSet[T]) Unite(other Set[T]) Set[T] {
	set := NewUnsafeSet(other.GetElements()...)
	for elem := range own.elems {
		set.elems[elem] = empty
	}

	return set
}

// Intersect 求交集（不修改原集合，生成一个新的集合）
func (own *UnsafeSet[T]) Intersect(other Set[T]) Set[T] {
	set := NewUnsafeSet[T]()
	for _, elem := range other.GetElements() {
		if _, ok := own.elems[elem]; ok {
			set.Add(elem)
		}
	}

	return set
}

// Complement 求补集（不修改原集合，生成一个新的集合）
func (own *UnsafeSet[T]) Complement(other Set[T]) Set[T] {
	set := NewUnsafeSet[T]()
	for _, elem := range other.GetElements() {
		if _, ok := own.elems[elem]; !ok {
			set.Add(elem)
		}
	}

	elems := other.GetMap()
	for elem := range own.elems {
		if _, ok := elems[elem]; !ok {
			set.Add(elem)
		}
	}

	return set
}

// Range 遍历并获取每个元素
func (own *UnsafeSet[T]) Range(fn func(T)) {
	for elem := range own.elems {
		fn(elem)
	}
}

// Filter 过滤集合，并返回过滤的元素
func (own *UnsafeSet[T]) Filter(fn func(T) bool) []T {
	elems := make([]T, 0, len(own.elems))
	for elem := range own.elems {
		if fn(elem) {
			elems = append(elems, elem)
		}
	}

	own.Delete(elems...)
	return elems
}

// Clone 克隆当前集合
func (own *UnsafeSet[T]) Clone() Set[T] {
	return NewUnsafeSet(own.GetElements()...)
}

// Clear 清空集合
func (own *UnsafeSet[T]) Clear() {
	own.elems = make(map[T]struct{})
}
